package com.iplant.ams.serviceImpl;

import com.iplant.ams.service.AMSBPMService;
import com.iplant.ams.service.po.dms.fault.DMSFaultBaseBPM;
import com.iplant.base.po.APIResult;
import com.iplant.base.po.OutResult;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.SessionConstants;
import com.iplant.base.utils.general.CalendarTool;
import com.iplant.base.utils.serializer.CloneTool;
import com.iplant.base.utils.general.DesUtil;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.base.utils.sql.orm.ORMUtils;
import com.iplant.basic.service.BFCService;
import com.iplant.basic.service.basicenum.bfc.BFCMessageStatus;
import com.iplant.basic.service.basicenum.bfc.BFCMessageType;
import com.iplant.basic.service.basicenum.bpm.BPMEventModule;
import com.iplant.basic.service.po.bfc.BFCHandleTaskMessage;
import com.iplant.basic.service.po.bfc.BFCMessage;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.basic.service.po.bpm.BPMActivitiHisTask;
import com.iplant.basic.serviceImpl.BFCServiceImpl;
import com.iplant.basic.serviceImpl.BPMServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @author Femi
 * 2019年12月27日12:46:35
 */
@Service
public class AMSBPMServiceImpl implements AMSBPMService{

    private static final Logger logger = LoggerFactory.getLogger(AMSBPMServiceImpl.class);

    public AMSBPMServiceImpl() {
    }

    private static AMSBPMService Instance;

    public static AMSBPMService getInstance() {
        if (Instance == null)
            Instance = new AMSBPMServiceImpl();
        return Instance;
    }

    @Override
    public ServiceResult<Object> BPM_RejectTo(BMSEmployee wLoginUser, String wTaskID, String targetActivityId,
                                              Object wData, String targetActivityName, int wFlowType) {
        ServiceResult<Object> wResult = new ServiceResult<>(0);
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            Map<String, Object> wDataMap = (Map<String, Object>) wData;
            List<BPMActivitiHisTask> wHisList = new ArrayList<>();
            if (wDataMap.containsKey("FlowID")) {
                wHisList = BPMServiceImpl.getInstance()
                        .BPM_GetHistoryInstanceByID(wLoginUser, StringUtils.parseInt(wDataMap.get("FlowID")))
                        .List(BPMActivitiHisTask.class);
            }

            // ①调用bpm服务驳回操作
            if (wHisList.stream().anyMatch(p -> p.ActivitiID.equals("RelevantDepartments_review"))) {
                List<BPMActivitiHisTask> wToCloseTaskList = wHisList.stream()
                        .filter(p -> p.ActivitiID.equals("RelevantDepartments_review")
                                && p.Status == 0 && !p.ID.equals(wTaskID))
                        .collect(Collectors.toList());
                Map<String, Object> wObjMap = CloneTool.Clone(wData, Map.class);
                if (wObjMap.containsKey("Remark")) {
                    wObjMap.put("Remark", "");
                }
                if (wObjMap.containsKey("Remark_txt_")) {
                    wObjMap.put("Remark_txt_", "");
                }
                for (BPMActivitiHisTask wBPMActivitiHisTask : wToCloseTaskList) {
                    Map<String, Object> wParams = new HashMap<String, Object>();
                    BMSEmployee wUser = ORMUtils.GetPoService(BMSEmployee.class).SelectPO(wLoginUser, wParams,
                            wErrorCode);
                    if (wUser != null && wUser.ID > 0) {
                        wUser.LoginName = DesUtil.encrypt(wUser.LoginName, SessionConstants.appSecret);
                        BPMServiceImpl.getInstance().BPM_RejectedSpecifiedActivity(wUser, wBPMActivitiHisTask.ID,
                                targetActivityId, wObjMap);
                    }
                }
            }
            APIResult wAPIResult = BPMServiceImpl.getInstance().BPM_RejectedSpecifiedActivity(wLoginUser, wTaskID,
                    targetActivityId, wData);
            if (wAPIResult == null) {
                wResult.FaultCode += "提示：驳回失败，BPM服务返回空!";
                return wResult;
            }
            if (wAPIResult.getResultCode() != 1000) {
                wResult.FaultCode += "提示：驳回失败。" + wAPIResult.getMsg();
                return wResult;
            }
            // ②更新主业务单据状态
            int wMessageID = 0;
            String wUpFlowName = "";
            String wCode = "";
            Calendar wCreateTime = Calendar.getInstance();

            switch (BPMEventModule.getEnumType(wFlowType)) {
                case FaultBaseAudit://故障检修
                    DMSFaultBaseBPM wNCRTask = CloneTool.Clone(wData, DMSFaultBaseBPM.class);
                    if (wNCRTask == null || wNCRTask.ID <= 0) {
                        wResult.FaultCode += "提示：data数据转换失败!";
                        return wResult;
                    }
                    wNCRTask.StatusText = "待" + targetActivityName;
                    ORMUtils.GetPoService(DMSFaultBaseBPM.class).UpdatePo(wLoginUser, wNCRTask, wErrorCode);

                    // ①更新数据
                    wMessageID = wNCRTask.ID;
                    wUpFlowName = wNCRTask.UpFlowName;
                    wCode = wNCRTask.Code;
                    wCreateTime = wNCRTask.CreateTime;
                    break;
                default:
                    break;
            }
            // ③创建待办信息
            if (wDataMap.containsKey("FlowID")) {
                wHisList = BPMServiceImpl.getInstance()
                        .BPM_GetHistoryInstanceByID(wLoginUser, StringUtils.parseInt(wDataMap.get("FlowID")))
                        .List(BPMActivitiHisTask.class);
            }
            wHisList = wHisList.stream().filter(p -> p.Status == 0).collect(Collectors.toList());
            if (wHisList.size() > 0) {
                BPMActivitiHisTask wHis = wHisList.get(0);
                String[] wStrs = wHis.Assignee.split(",");

                List<BFCMessage> wBFCMessageList = new ArrayList<>();
                BFCMessage wMessage;
                SimpleDateFormat wSDF = new SimpleDateFormat("yyyyMMdd");
                int wShiftID = Integer.parseInt(wSDF.format(Calendar.getInstance().getTime()));
                for (String wStr : wStrs) {
                    int wUserID = StringUtils.parseInt(wStr);
                    // 发送任务消息到人员
                    wMessage = new BFCMessage();
                    wMessage.Active = 0;
                    wMessage.CompanyID = 0;
                    wMessage.CreateTime = Calendar.getInstance();
                    wMessage.EditTime = Calendar.getInstance();
                    wMessage.ID = 0;
                    wMessage.MessageID = wMessageID;
                    wMessage.StepID = StringUtils.parseInt(wHis.ID);
                    wMessage.Title = StringUtils.Format("{0}", wCode);
                    wMessage.MessageText = StringUtils.Format("模块：{0} 发起人：{1}  发起时刻：{2} 待{3}",
                                    BPMEventModule.getEnumType(wFlowType).getLabel(), wUpFlowName,
                                    StringUtils.parseCalendarToString(wCreateTime, "yyyy-MM-dd HH:mm"),
                                    wHis.Name)
                            .trim();
                    wMessage.ModuleID = wFlowType;
                    wMessage.ResponsorID = wUserID;
                    wMessage.ShiftID = wShiftID;
                    wMessage.StationID = 0;
                    wMessage.Type = BFCMessageType.Task.getValue();
                    wBFCMessageList.add(wMessage);
                }
                BFCServiceImpl.getInstance().BFC_UpdateMessageList(wLoginUser, wBFCMessageList);
            }

            //完成待办

            BFCService.mBFCHandleTaskMessageResource.add(new BFCHandleTaskMessage(wLoginUser, wLoginUser.ID,
                    StringUtils.parseListArgs(wMessageID), wFlowType,
                    StringUtils.parseInt(wTaskID), BFCMessageStatus.Finished.getValue(), 1, CalendarTool.getBasicDate()));

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            logger.error(e.toString());
        }
        return wResult;
    }
    //endregion
}
